package com.eunion.web.admin.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.eunion.fileserver.upload.FileUploadFactory;
import com.eunion.fileserver.upload.FileUploadHelper;
import com.eunion.fileserver.upload.FileVo;
import com.eunion.fileserver.upload.JsonFileVo;

/**
 * 文件相关api. files
 * @since 2017年2月17日
 */
@Controller
@RequestMapping("/files")
public class FilesController {

    private static final Logger LOG = LoggerFactory.getLogger(FilesController.class);

    private static final String CONTENT_TYPE = "text/html; charset=UTF-8";

    @RequestMapping(method = RequestMethod.POST)
    public @ResponseBody JsonFileVo upload(MultipartHttpServletRequest request, HttpServletResponse response) {
        LOG.debug("uploadPost called begian ====");
        JsonFileVo vo = new JsonFileVo(false, "请求非法.");
        FileVo fv = new FileVo();
        try {
            fv.setPath(request.getParameter("path"));
            Iterator<String> itr = request.getFileNames();
            MultipartFile mpf;
            while (itr.hasNext()) {
                mpf = request.getFile(itr.next());
                LOG.debug("文件上传准备 {}", mpf.getOriginalFilename());
                fv.setSize(mpf.getSize());
                fv.setType("." + FileUploadHelper.getExtensionName(mpf.getOriginalFilename()));// 设置后缀
                fv.setNameOrg(mpf.getOriginalFilename());
                fv.setFileInputStream(mpf.getInputStream());
                LOG.debug("文件上传meta:{}", fv);
                // 有效性检验
                if (StringUtils.isEmpty(fv.getType()) || null == fv.getFileInputStream() || StringUtils.isEmpty(fv.getNameOrg())) {
                    LOG.warn("文件上传数据不足,类型或无上传文件,结束上传.");
                    continue;
                }
                FileUploadFactory.uploadFileInputStream(fv);
                if (fv.isUpload()) {
                    String pathUrl = FileUploadHelper.getInstance().getFileServerUrl() + fv.getRelativePath();
                    vo.setPathUrl(pathUrl);
                    vo.setPath(fv.getRelativePath());
                    vo.setNameOrg(fv.getNameOrg());
                    vo.setNameNew(fv.getNameNew());
                    vo.setSize(fv.getSize());
                    vo.setFlag(true);
                    vo.setMsg("上传成功");
                    LOG.debug("文件上传OK:{} -> {}", fv.getNameOrg(), fv.getRelativePath());
                } else {
                    vo.setMsg(fv.getErrorMsg());
                    LOG.error("文件上传失败:{} -> {}", fv.getNameOrg(), fv.getErrorMsg());
                }
                break;// 先只考虑一个上传的情况

            }
        } catch (Exception e) {
            LOG.error("Could not upload file ", e);
        }
        LOG.debug("uploadPost called end ====");
        return vo;
    }

    /**
     * 下载.
     */
    @RequestMapping("/downLoad")
    public String doDownLoad(HttpServletRequest request, HttpServletResponse response, String fileName, String downName)
        throws Exception {
        response.setContentType(CONTENT_TYPE);
        downName = URLDecoder.decode(downName, "UTF-8");
        String downnameEncode = downName;
        String filename = fileName;
        InputStream ins = FileUploadFactory.getFileInputStream(fileName);
        if (ins == null) {
            response.getWriter().write("<script>alert('该文献暂时无法提供相关下载！！');</script>");
            return null;
        }
        downloadStream(request, response, ins, downnameEncode, filename, null);
        return null;
        // 添加FTP文件的下载,兼容之前的下载模式
        // if (ServiceConstants.FTP_USE) {
        // InputStream ins = new FileUploadFactory().getFileInputStream(fileName);
        // if (ins == null) {
        // response.getWriter().write("<script>alert('该文献暂时无法提供相关下载！！');</script>");
        // return null;
        // }
        // downloadStream(request, response, ins, downnameEncode, filename, null);
        // return null;
        // } else {
        // // 创建file对象
        // String fileUrl = ServiceConstants.UPLOAD_PATH + fileName;
        // File file = new File(fileUrl);
        //
        // // 如果下载文件不存在则提示用户并且返回
        // if (!file.exists()) {
        // response.getWriter().write("<script>alert('该文献暂时无法提供相关下载！！');</script>");
        // return null;
        // }
        //
        // // 读出文件到i/o流
        //// FileReader fis = new FileReader(file);
        //// BufferedReader buff = new BufferedReader(fis);
        // // 设置response的编码方式 response.setContentType("application/x-msdownload");
        // // 写明要下载的文件的大小
        // // 设置附加文件名,并且解决中文乱码
        // FileInputStream stream = new FileInputStream(file);
        // downloadStream(request, response, stream, downnameEncode, filename, (int) file.length());
        // return null;
        // }
    }

    /**
     * 文件下载
     * @param response
     * @param is 文件输入流
     * @param fileName 下载的文件名称
     * @param encoding 编码格式
     */
    private void downloadStream(HttpServletRequest request, HttpServletResponse response, InputStream is, String downnameEncode, String downName, Integer length) {
        if (is == null || StringUtils.isBlank(downName)) {
            return;
        }

        BufferedInputStream bis = null;
        OutputStream os = null;
        BufferedOutputStream bos = null;

        try {
            bis = new BufferedInputStream(is);
            os = response.getOutputStream();
            bos = new BufferedOutputStream(os);
            // 设定下载名称
            if (null != length) {
                response.setContentLength(length);
            }
            // String agent = request.getHeader("USER-AGENT");
            // if (null != agent && -1 != agent.indexOf("MSIE")) {//IE
            // downnameEncode = java.net.URLEncoder.encode(downnameEncode, "UTF-8");
            // } else if (null != agent && -1 != agent.indexOf("Mozilla")) {
            // response.setCharacterEncoding("utf-8");//+ ".xlsx"
            // downnameEncode = new String(downnameEncode.getBytes("UTF-8"), "iso-8859-1");
            // } else {
            // downnameEncode = java.net.URLEncoder.encode(downnameEncode, "UTF-8");
            // }//from http://lgbolgger.iteye.com/blog/2108396
            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(downnameEncode, "UTF-8") + ";filename*=UTF-8''" + URLEncoder.encode(downnameEncode, "UTF-8"));
            // response.setHeader("Content-Disposition", "attachment;filename=" + downnameEncode);

            byte[] buffer = new byte[1024];
            int len = bis.read(buffer);
            while (len != -1) {
                bos.write(buffer, 0, len);
                len = bis.read(buffer);
            }

            bos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {}
            }

            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {}
            }
        }
        // /**
        // * 文件下载
        // * @param response
        // * @param is 文件输入流
        // * @param fileName 下载的文件名称
        // * @param encoding 编码格式
        // */
        // private void downloadStream(HttpServletRequest request, HttpServletResponse response, InputStream is, String downnameEncode, String
        // downName, Integer length)
        // throws IOException {
        // if (is == null || StringUtils.isBlank(downName)) {
        // return;
        // }
        //
        // BufferedInputStream bis = null;
        // OutputStream os = null;
        // BufferedOutputStream bos = null;
        //
        // try {
        // bis = new BufferedInputStream(is);
        // os = response.getOutputStream();
        // bos = new BufferedOutputStream(os);
        // //设定下载名称
        // if (null != length) {
        // response.setContentLength(length);
        // }
        // response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(downnameEncode, "UTF-8") + ";filename*=UTF-8''" +
        // URLEncoder.encode(downnameEncode, "UTF-8"));
        // byte[] buffer = new byte[1024];
        // int len = bis.read(buffer);
        // while (len != -1) {
        // bos.write(buffer, 0, len);
        // len = bis.read(buffer);
        // }
        // bos.flush();
        // } finally {
        // if (bis != null) {
        // try {
        // bis.close();
        // } catch (IOException e) {
        // LOG.error("关闭流出错,bis", e);
        // }
        // }
        //
        // if (is != null) {
        // try {
        // is.close();
        // } catch (IOException e) {
        // LOG.error("关闭流出错,is", e);
        // }
        // }
        // }
        // }
        //
        // public void doGet(HttpServletRequest request, HttpServletResponse response) {
        // String fileName = "";//namepath
        // String downnameEncode = "";
        // try {
        // response.setContentType(CONTENT_TYPE);
        // // String gch = request.getParameter("gch");
        // downnameEncode = request.getParameter("downName");
        // fileName = request.getParameter("fileName");
        // downnameEncode = URLDecoder.decode(downnameEncode, "UTF-8");
        // String rootPath = FUtils.getRootPath();
        // // 创建file对象
        // String fileUrl = rootPath + fileName;
        // File file = new File(fileUrl);
        //
        // // 如果下载文件不存在则提示用户并且返回
        // if (!file.exists()) {
        // response.getWriter().write("<script>alert('该文献暂时无法提供相关下载！！');</script>");
        // return;
        // }
        //
        // // 读出文件到i/o流
        // FileInputStream stream = new FileInputStream(file);
        // downloadStream(request, response, stream, downnameEncode, fileName, (int) file.length());
        // } catch (Exception e) {
        // LOG.error("文件下载失败.e", e);
        // try {
        // response.getWriter().write("<script>alert('文件下载失败！');</script>");
        // } catch (IOException e1) {
        // LOG.error("文件下载失败.e", e1);
        // }
        // }
        // }
    }
}
